package com.seven.first.suite.result;

import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

public class BizResult<T> {
	public final static int SUCCESS = 200;
	
	
	private int status;
	private String errorMsg;
	private T data;
	
	private BizResult() {}
	
	private BizResult(int status,T data, String errorMsg){
		this.status = status;
		this.data = data;
		this.errorMsg = errorMsg;
	}  
	 
	
	//================================构造方法================================================
	public static <T> BizResult<T> ok(){
		return new BizResult<>(SUCCESS,null,null);
	}
	public static <T> BizResult<T> ok(T data){
		return new BizResult<>(SUCCESS,data,null);
	} 
	public static <T> BizResult<T> error(int status,String errorMsg){
		return new BizResult<>(status,null,errorMsg);
	}
	public static <T> BizResult<T> error(int status,String errorMsg,T data){
		return new BizResult<>(status,data,errorMsg);
	}  
	public <U> BizResult<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (isFailure()) {
        	return BizResult.error(this.status,this.errorMsg);
        }else { 
            return BizResult.ok(mapper.apply(this.data)) ; 
        }
    }
	public void ifSuccess(Consumer<BizResult<T>> consumer) {
		Objects.requireNonNull(consumer);
		
		if (isSuccess()) {
			consumer.accept(this);
		}
	}
	public void ifPresent(Consumer<BizResult<T>> consumer) {
		Objects.requireNonNull(consumer);
		
		if (isPresent()) {
			consumer.accept(this);
		}
	} 
	public boolean isSuccess() {
		return SUCCESS == status;
	}
	public boolean isFailure() {
		return ! isSuccess();
	}
	public boolean isPresent() {
		return isSuccess() && data != null;
	}
	
	 
	public int getStatus() {
		return status;
	}

	public BizResult<T> setStatus(int status) {
		this.status = status;
		return this;
	}
 
	public String getErrorMsg() {
		return errorMsg;
	}
 
	public BizResult<T> setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
		return this;
	}
 
	public T getData() {
		return data;
	}

	public BizResult<T> setData(T data) {
		this.data = data;
		return this;
	}
	
	
}
